#include <string.h>
#include <glib.h>
#include "callbacks.h"
#include "config.h"
#include "nls.h"
#include "ttorrent.h"
#include "operations.h"
#include "views.h"

GtkWidget*
create_dict_entry( const gchar* s, gint* value)
{
  GtkWidget * hbox = gtk_hbox_new(TRUE, 0);
  GtkWidget * child = gtk_label_new(s);
  gtk_misc_set_alignment(GTK_MISC(child), 0.0, 0.0);
  gtk_box_pack_start(GTK_BOX(hbox), child, FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(hbox), gtk_spin_button_new_with_range(0, 10, 1), FALSE, FALSE, 0);
  child = gtk_alignment_new(1.0, 0.0, 1.0, 1.0);
  gtk_container_add(GTK_CONTAINER(child), hbox);
  return child;
}


void
add_action_callback (GtkWidget * widget, gpointer data)
{
    TTorrent * ttorrent = (TTorrent*) data;
    GtkWidget *dialog = gtk_file_chooser_dialog_new (_("Open torrent file"),
        GTK_WINDOW (ttorrent->window),
        GTK_FILE_CHOOSER_ACTION_OPEN,
        GTK_STOCK_CANCEL,
        GTK_RESPONSE_CANCEL,
        GTK_STOCK_OPEN,
        GTK_RESPONSE_ACCEPT,
        NULL);
    GtkFileFilter * filter = gtk_file_filter_new ();
    gint resp;

    gtk_file_filter_set_name (filter, "torrent");

    gtk_file_filter_add_mime_type (filter, "application/x-bittorrent");
    gtk_file_filter_add_pattern (filter, "*.torrent");

    gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
    // Set this filter as the default.
    gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter);

    filter = gtk_file_filter_new ();
    gtk_file_filter_set_name (filter, _("All Files"));
    gtk_file_filter_add_pattern (filter, "*");

    gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
    resp = gtk_dialog_run (GTK_DIALOG (dialog));

    gchar *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
    gtk_widget_destroy (dialog);

    if (resp != GTK_RESPONSE_ACCEPT) return;

    if(add_torrent(ttorrent, filename, NULL)) return;

    dialog = gtk_dialog_new_with_buttons(
        _("Error"),
        GTK_WINDOW (ttorrent->window),
        GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
        GTK_STOCK_OK,
        GTK_RESPONSE_OK,
        NULL);

    GtkWidget * hbox = gtk_hbox_new(FALSE, 2);
    gtk_box_pack_start(GTK_BOX(hbox), gtk_image_new_from_stock(GTK_STOCK_DIALOG_ERROR , GTK_ICON_SIZE_DIALOG), TRUE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(_("Torrent already added")), TRUE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), GTK_WIDGET(hbox),  TRUE, TRUE, 0);
    gtk_widget_show_all(hbox);
    gtk_dialog_run (GTK_DIALOG (dialog));
    gtk_widget_destroy(dialog);
}

void
remove_action_callback (GtkWidget * widget, gpointer data)
{
    TTorrent * ttorrent = (TTorrent *) data;
    gint resp;
    GtkWidget * dialog;
    GtkTreeSelection * sel;
    GtkWidget * hbox;
    GtkTreeModel * model;
    GtkTreeIter iter;
    GtkTreeModel * child_model;
    GtkTreeIter child_iter;

    sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(ttorrent->torrents_view));
    if(!gtk_tree_selection_get_selected(sel, &model, &iter)) return;

    dialog = gtk_dialog_new_with_buttons(
        _("Confirm remove"),
        GTK_WINDOW (ttorrent->window),
        GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
        GTK_STOCK_CANCEL,
        GTK_RESPONSE_CANCEL,
        GTK_STOCK_OK,
        GTK_RESPONSE_OK,
        NULL);

    hbox = gtk_hbox_new(FALSE, 0);
    gtk_box_pack_start(GTK_BOX(hbox), gtk_image_new_from_stock(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG), TRUE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(_("Remove torrent?")), TRUE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), GTK_WIDGET(hbox),  TRUE, TRUE, 0);
    gtk_widget_show_all(hbox);

    resp = gtk_dialog_run (GTK_DIALOG (dialog));
    gtk_widget_destroy(dialog);
    if(resp != GTK_RESPONSE_OK) return;

    gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(model), &child_iter, &iter);
    child_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(model));

    remove_torrent(child_model, &child_iter, ttorrent);

    if(gtk_tree_model_get_iter_first(model, &iter))
      gtk_tree_selection_select_iter(sel, &iter);
}

void
about_action_callback (GtkWidget * widget, gpointer data)
{
  gtk_show_about_dialog (
    GTK_WINDOW(((TTorrent*) data)->window),
    "name", _("Tom's Torrent"),
    "version", VERSION,
    "copyright", "Copyright © 2007 Tomasz Bloch, Tomasz Socha",
    "comments", _("GTK+ Bittorrent client"),
    NULL);
}

void
options_action_callback (GtkWidget * widget, gpointer data)
{
  TTorrent * tt = (TTorrent *) data;
  TSettings * ts = g_slice_dup(TSettings, tt->settings);

  ts->save_dir = g_strdup( tt->settings->save_dir );
  GtkWidget * dialog;
  GtkWidget * child;
  GtkWidget * box;
  gint resp;

  dialog = gtk_dialog_new_with_buttons (
        _("Preferences"),
        GTK_WINDOW (tt->window),
        GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
        GTK_STOCK_CANCEL,
        GTK_RESPONSE_CANCEL,
        GTK_STOCK_OK,
        GTK_RESPONSE_OK,
        NULL
  );

  child = gtk_scrolled_window_new(NULL, NULL);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (child),
      GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

  box = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
  gtk_alignment_set_padding(GTK_ALIGNMENT(box), 4, 4, 4, 4);
  gtk_container_add(GTK_CONTAINER(box), create_options_view(ts) );
  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (child), GTK_WIDGET(box));

  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), child,  TRUE, TRUE, 0);
  gtk_window_set_default_size(GTK_WINDOW(dialog), 640, 480);
  gtk_widget_show_all(GTK_WIDGET(dialog));

  resp = gtk_dialog_run (GTK_DIALOG (dialog));

  if(resp != GTK_RESPONSE_OK)
  {
    g_free(ts->save_dir);
    g_slice_free(TSettings, ts);
  }
  else
  {
    g_free(tt->settings->save_dir);
    g_slice_free(TSettings, tt->settings);
    tt->settings = ts;
    apply_settings(tt);
  }
  gtk_widget_destroy(dialog);
}

void
commit_pri_action_callback (GtkWidget *widget, gpointer data)
{
  TTorrent * tt = (TTorrent *) data;
  GtkTreeSelection * sel;
  GtkTreeModel * model;
  GtkTreeIter iter;
  GtkTreeIter sort_iter;

  sel = gtk_tree_view_get_selection(tt->torrents_view);
  if (!gtk_tree_selection_get_selected(sel, &model, &sort_iter)) return;

  gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(model), &iter, &sort_iter);
  model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(model));
  prioritize_files(model, &iter, 0);
}

void
rollback_pri_action_callback (GtkWidget *widget, gpointer data)
{
  TTorrent * tt = (TTorrent *) data;
  GtkTreeSelection * sel;
  GtkTreeModel * model;
  GtkTreeIter iter;
  GtkTreeIter sort_iter;
  gboolean valid;

  sel = gtk_tree_view_get_selection(tt->torrents_view);
  if (!gtk_tree_selection_get_selected(sel, &model, &sort_iter)) return;

  gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(model), &iter, &sort_iter);
  model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(model));
  prioritize_files(model, &iter, 0);
}

gboolean destroy_handler(GtkWidget * widget, gpointer data)
{
    gtk_widget_hide_all(GTK_WIDGET(widget));
    gtk_main_quit ();
    return FALSE;
}

gboolean delete_event_handler(GtkWidget * widget, GdkEvent * event, gpointer data)
{
  gtk_window_set_skip_taskbar_hint(GTK_WINDOW(widget), TRUE);
  gtk_window_set_skip_pager_hint(GTK_WINDOW(widget), TRUE);
  gtk_window_iconify(GTK_WINDOW(widget));
  gtk_widget_hide_all(widget);
  gtk_status_icon_set_visible(GTK_STATUS_ICON(data), TRUE);

  return TRUE;
}

void
exit_action_callback (GtkWidget * widget, gpointer data)
{
    TTorrent * ttorrent = (TTorrent *) data;
    gint resp;
    GtkWidget * hbox = gtk_hbox_new(FALSE, 2);
    GtkWidget *dialog = gtk_dialog_new_with_buttons(
        _("Confirm quit"),
        GTK_WINDOW (ttorrent->window),
        GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
        GTK_STOCK_CANCEL,
        GTK_RESPONSE_CANCEL,
        GTK_STOCK_QUIT,
        GTK_RESPONSE_CLOSE,
        NULL);

    gtk_box_pack_start(GTK_BOX(hbox), gtk_image_new_from_stock(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG), TRUE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(_("Exit program?")), TRUE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), GTK_WIDGET(hbox),  TRUE, TRUE, 0);
    gtk_widget_show_all(hbox);

    resp = gtk_dialog_run (GTK_DIALOG (dialog));
    gtk_widget_destroy(dialog);

    if(resp == GTK_RESPONSE_CLOSE)
    //if(!delete_event_handler(ttorrent->window, data))
      destroy_handler(ttorrent->window, NULL);
}

void
pause_resume_action_callback (GtkWidget *widget, gpointer data)
{
    TTorrent * ttorrent = (TTorrent *) data;
    GtkTreeSelection *selection;
    GtkTreeModel *model;
    GtkTreeIter iter;

    GtkTreeModel *child_model;
    GtkTreeIter child_iter;

    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ttorrent->torrents_view));

    if (!gtk_tree_selection_get_selected(selection, &model, &iter)) return;

    gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(model), &child_iter, &iter);
    child_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(model));
    pause_resume_torrent(child_model, &child_iter);
}

void
move_up_action_callback (GtkWidget *widget, gpointer data)
{
    /* we passed the view as data when we connected the signal */
    TTorrent * ttorrent = (TTorrent *) data;
    GtkTreeView *treeview = GTK_TREE_VIEW(ttorrent->torrents_view);
    GtkTreeSelection *selection;
    GtkTreeModel *model;
    GtkListStore *store;
    GtkTreeIter iter;
    GtkTreeIter sel_iter;
    gint value;
    gint i;

    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));

    if (!gtk_tree_selection_get_selected(selection, &model, &iter)) return;

    gtk_tree_model_get(
      model, &iter,
      COL_T_NUMBER, &value,
    -1);
    if(value <= 1)
    {
      return;
    };

    gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(model), &sel_iter, &iter);
    model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(model));
    gboolean valid = gtk_tree_model_get_iter_first(model, &iter);

    for(i=1;i<value-1;i++)
      valid = gtk_tree_model_iter_next(model, &iter);

    store = GTK_LIST_STORE(model);
    gtk_list_store_set(store, &iter, COL_T_NUMBER, value, -1);
    gtk_list_store_set(store, &sel_iter, COL_T_NUMBER, value-1, -1);

    gtk_list_store_swap(store, &sel_iter, &iter);
}

void
move_down_action_callback (GtkWidget *widget, gpointer data)
{
    TTorrent * ttorrent = (TTorrent *) data;
    GtkTreeView *treeview = GTK_TREE_VIEW(ttorrent->torrents_view);
    GtkTreeSelection *selection;
    GtkTreeModel *model;
    GtkListStore *store;
    GtkTreeIter iter;
    GtkTreeIter sel_iter;
    gint value;
    gboolean valid;

    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));

    if (!gtk_tree_selection_get_selected(selection, &model, &iter)) return;
    gtk_tree_model_get(
      model, &iter,
      COL_T_NUMBER, &value,
    -1);

    //fprintf(stderr, "move down ttorrent->contt=%d, value=%d\n", ttorrent->count, value);
    if(value >= ttorrent->count) return;

    gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(model), &sel_iter, &iter);
    model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(model));

    memcpy(&iter, &sel_iter, sizeof(GtkTreeIter));

    store = GTK_LIST_STORE(model);
    gtk_list_store_set(store, &sel_iter, COL_T_NUMBER, value+1, -1);

    valid = gtk_tree_model_iter_next(model, &sel_iter);
    gtk_list_store_set(store, &sel_iter, COL_T_NUMBER, value, -1);

    gtk_list_store_swap(store, &sel_iter, &iter);
}


void
torrents_view_popup_menu (GtkWidget *treeview, GdkEventButton *event, gpointer data)
{
    GtkWidget *menu, *menuitem;

    menu = gtk_menu_new();

    menuitem = gtk_image_menu_item_new_with_label(_("Pause/Resume"));
    gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), gtk_image_new_from_stock(GTK_STOCK_CONVERT, GTK_ICON_SIZE_MENU));
    g_signal_connect(menuitem, "activate",
                     (GCallback) pause_resume_action_callback, data);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);

    menuitem = gtk_separator_menu_item_new();
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);

    menuitem = gtk_image_menu_item_new_with_label(_("Move up"));
    gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), gtk_image_new_from_stock(GTK_STOCK_GO_UP, GTK_ICON_SIZE_MENU));
    g_signal_connect(menuitem, "activate",
                     (GCallback) move_up_action_callback, data);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);

    menuitem = gtk_image_menu_item_new_with_label(_("Move down"));
    gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), gtk_image_new_from_stock(GTK_STOCK_GO_DOWN, GTK_ICON_SIZE_MENU));
    g_signal_connect(menuitem, "activate",
                     (GCallback) move_down_action_callback, data);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);

    gtk_widget_show_all(menu);

    /* Note: event can be NULL here when called from torrents_view_on_popup_menu;
     *  gdk_event_get_time() accepts a NULL argument */
    gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
                   (event != NULL) ? event->button : 0,
                   gdk_event_get_time((GdkEvent*)event));
}


gboolean
torrents_view_on_button_pressed (GtkWidget *treeview, GdkEventButton *event, gpointer data)
{
  // single click with the right mouse button?
  if (event->type == GDK_BUTTON_PRESS  &&  event->button == 3)
  {
      /*  optional: select row if no row is selected or only
       *  one other row is selected */
    if (1)
    {
        GtkTreeSelection *selection;

        selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));

        GtkTreePath *path;

            // Get tree path for row that was clicked
        if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeview), (gint) event->x, (gint) event->y, &path, NULL, NULL, NULL))
        {
          //gtk_tree_selection_unselect_all(selection);
          gtk_tree_selection_select_path(selection, path);
          gtk_tree_path_free(path);
        }
    } // end of optional bit

    torrents_view_popup_menu(treeview, event, data);

    return TRUE; /* we handled this */
  }

  return FALSE; /* we did not handle this */
}


gboolean
torrents_view_on_popup_menu (GtkWidget *treeview, gpointer data)
{
    torrents_view_popup_menu(treeview, NULL, data);

    return TRUE; /* we handled this */
}

void
icon_popup_menu(GtkStatusIcon * icon, guint button, guint time, gpointer data)
{
    GtkWidget *menu, *menuitem;

    menu = gtk_menu_new();
    menuitem = gtk_image_menu_item_new_with_label(_("Add torrent"));
    gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_MENU));
    g_signal_connect(menuitem, "activate",
                     (GCallback) add_action_callback, data);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);

    menuitem = gtk_separator_menu_item_new();
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);

    menuitem = gtk_image_menu_item_new_with_label(_("Exit"));
    gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), gtk_image_new_from_stock(GTK_STOCK_QUIT, GTK_ICON_SIZE_MENU));
    g_signal_connect(menuitem, "activate",
                     (GCallback) exit_action_callback, data);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);

    gtk_widget_show_all(menu);

    /* Note: event can be NULL here when called from torrents_view_on_popup_menu;
     *  gdk_event_get_time() accepts a NULL argument */
    gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, button, time);
}

void
icon_activate(GtkStatusIcon * icon, gpointer data)
{
  TTorrent * ttorrent = (TTorrent *) data;
  gtk_window_set_skip_taskbar_hint(GTK_WINDOW(ttorrent->window), FALSE);
  gtk_window_set_skip_pager_hint(GTK_WINDOW(ttorrent->window), FALSE);
  gtk_window_deiconify(GTK_WINDOW(ttorrent->window));
  gtk_widget_show_all(ttorrent->window);
  gtk_status_icon_set_visible(icon, FALSE);
}



